﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FlashCards.NeuralNetworks
{
    public class Neuron
    {
        static Random _rand = new Random();
        public double Error { get; set; }

        public double Output { get; set; }
        public double Potential { get; set; }

        public Guid Guid { get; set; }

        public Neuron(int inputCount)
        {
            Inputs = new List<Neuron>();
            Weights = new List<double>();
            PrevWeights = new List<double>();

            Guid = Guid.NewGuid();

            for (int i = 0; i < inputCount; i++)
            {
                Weights.Add(_rand.NextDouble());
                PrevWeights.Add(0);
            }
        }

        public Neuron(int inputCount, Guid guid) : this(inputCount)
        {
            Guid = guid;
        }

        public Neuron(List<double> weights, Guid guid)
        {
            Inputs = new List<Neuron>();
            Weights = new List<double>();
            PrevWeights = new List<double>();

            Guid = guid;

            for (int i = 0; i < weights.Count; i++)
            {
                Weights.Add(weights[i]);
                PrevWeights.Add(0);
            }
        }


        public List<Neuron> Inputs { get; set; }
        public List<double> Weights { get; set; }
        public List<double> PrevWeights { get; set; }

        public virtual double CalculateActivationFunction()
        {
            CalculateMembranPotential();
            Output = 1.0 / (1.0 + Math.Pow(Math.E, -Potential));
            return Output;
        }

        public virtual double CalculateDerivative()
        {
            var x = Potential;
            return (1 - Output * Output);
        }

        public double CalculateMembranPotential()
        {
            double sum = 0;
            for (int i = 0; i < Inputs.Count; i++)
            {
                sum += Inputs[i].CalculateActivationFunction() * Weights[i];
            }

            Potential = sum;

            return sum;
        }
    }
}
